﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using SpectationClient.DataBaseDescription;
using Npgsql;

namespace SpectationClient.GUI
{
    public partial class DBConnection : Form
    {
        String cstr;
        public DBConnection()
        {
            InitializeComponent();
            this.Icon = Resources.Icon;
            String pathInfo = String.Format(@"{0}\{1}\{2}",
                Application.StartupPath,
                Properties.Settings.Default.DIR_RESOURCES,
                Properties.Settings.Default.FN_DB_INFO_XML);
            if(!File.Exists(pathInfo)) throw new Exception(String.Format("File {0} does not exist.", pathInfo));
            SPECTATION_INFO_Reader Reader = new SPECTATION_INFO_Reader(null, pathInfo);
            List<SPECTATION_INFO_Reader.DataBaseConnectionInfo> DBLs = Reader.ReadDBLocation();
            List<SPECTATION_INFO_Reader.DataBaseConnectionInfo> DBUs = Reader.ReadDBUsers();

            cbUser.SelectedValueChanged += new EventHandler(cb_SelectedValueChanged);
            cbServer.SelectedValueChanged +=new EventHandler(cb_SelectedValueChanged);

            
            cbServer.DataSource = DBLs;
            cbServer.DisplayMember = "Value";
            cbServer.ValueMember = "Value";
            TT.SetToolTip(cbServer, ((SPECTATION_INFO_Reader.DataBaseConnectionInfo)cbServer.SelectedItem).Description);

            cbUser.DataSource = DBUs;
            cbUser.DisplayMember = "Value";
            cbUser.ValueMember = "Value";
            TT.SetToolTip(cbUser, ((SPECTATION_INFO_Reader.DataBaseConnectionInfo)cbServer.SelectedItem).Description);

            
        }

        void cb_SelectedValueChanged(object sender, EventArgs e) {
            ComboBox cb = (ComboBox)sender;
            TT.SetToolTip(cb, ((SPECTATION_INFO_Reader.DataBaseConnectionInfo)cbServer.SelectedItem).Description);
        }

        private void btOk_Click(object sender, EventArgs e) {
            cstr = getConnectionString();
            if (testConnectionString(cstr)) {
                this.DialogResult = DialogResult.OK;
            } 
        }

        public String ConnectionString {
            get { return this.cstr;}
        }

        private void btTest_Click(object sender, EventArgs e)
        {
            testConnectionString(getConnectionString());
        }

        private String readSelectedValue(ComboBox cbox) {
            return (String)((cbox.SelectedValue != null) ? cbox.SelectedValue : cbox.Text);
        }
        /// <summary>
        /// reads connection properties
        /// </summary>
        /// <returns>connection string</returns>
        private String getConnectionString() { 
         NpgsqlConnectionStringBuilder csb = new NpgsqlConnectionStringBuilder();
            csb.CommandTimeout = 30;
            csb.Host = readSelectedValue(cbServer);
            csb.Add("PASSWORD", tbPWD.Text); 
            
            csb.Protocol = ProtocolVersion.Unknown;
            csb.UserName = this.readSelectedValue(cbUser);
            csb.Database = tbDB.Text;
            csb.SSL = true;
            csb.CommandTimeout = Properties.Settings.Default.DEF_COMMAND_TIMEOUT;
            csb.Timeout = Properties.Settings.Default.DEF_CONNECTION_TIMEOUT;
            int t;
            if (!int.TryParse(tbPort.Text, out t)) {
                this.rtbInfo.AppendText(csb.Port + "ist kein Port");
            } else { csb.Port = t; };
            
            return csb.ConnectionString;
        }

        //Testet ConnectionString
        private bool testConnectionString(String cstr)
        {
            this.rtbInfo.Clear();
            NpgsqlConnection con = new NpgsqlConnection(cstr);
           
            bool ret = true;
            this.Cursor = Cursors.WaitCursor;
            try {
                con.Open();
                // TEST DB VERSION
                this.rtbInfo.Text = "Connection successful";
            } catch (NpgsqlException ex) {
                String errStr = "";
                if (ex.Errors.Count == 0) errStr = ex.BaseMessage;

                foreach(NpgsqlError error in ex.Errors) {
                   
                    switch (error.Message){
                        case "No such host known" : errStr = error.Message + ":\""+this.readSelectedValue(cbServer)+"\\n";
                            break;
                        default: errStr += error.Message + "\n"; 
                            break;
                    }
                }
                this.rtbInfo.Text = errStr;
                ret = false;
            } catch (ArgumentException ex) {
                this.rtbInfo.AppendText(ex.Message);
                ret = false;
            } catch (Exception ex) {
                this.rtbInfo.AppendText(ex.Message);
                ret = false;
            } finally { 
                con.Close(); 
            }
            this.Cursor = this.DefaultCursor;
            return ret;
        }

        private void btClear_Click(object sender, EventArgs e)
        {
            this.rtbInfo.Clear();
        }

        private void btCancel_Click(object sender, EventArgs e) {
            this.Close();
        }

    }
}
